import {WidgetBaseSession} from './base'
import {BoolValue, fromAny, Int32Value, StringValue, toAny} from "../../proto";
import { Modal } from '../../modal'

class WidgetSpinnerSession extends WidgetBaseSession {
    private spinner: HTMLElement
    private prompt: string
    private onSelectChangedListener: () => void
    private dialogMode: boolean
    private items: Array<string>
    private selectedIndex: number

    constructor(render: HTMLElement) {
        super('Spinner', render)
    }

    createWidget(...argv): HTMLElement {
        this.dialogMode = fromAny(argv[0], BoolValue)
        if (this.dialogMode) {
            this.spinner = document.createElement("button")
            this.spinner.onclick = () => this.show()
        } else
            this.spinner = document.createElement("select")
        this.spinner.ariaRoleDescription = '下拉框'
        return this.spinner
    }

    onDestroy() {
        if (this.onSelectChangedListener)
            this.spinner.removeEventListener('selectionchange', this.onSelectChangedListener)
        super.onDestroy();
    }

    onReceive(name: String, sessionId: number, futureId: number, ...argv) {
        switch (name) {
            case 'getPrompt':
                this.onGetPrompt(sessionId, futureId)
                return;
            case 'setPrompt':
                this.onSetPrompt(...argv)
                return;
            case 'select':
                this.onSelect(...argv)
                return;
            case  'setItems':
                this.onSetItems(...argv)
                return;
            case "setOnItemSelectedListener":
                this.setOnItemSelectedListener(...argv)
                return;
            default:
                super.onReceive(name, sessionId, futureId, ...argv);
        }
    }

    private show() {
        const config = {
            title: this.prompt,
            template: ''
        }
        const dialog = new Modal(config)
        const select = document.createElement('select')
        this.items.forEach((item, index) => {
            const option = document.createElement('option')
            option.value = option.text = item
            if (this.selectedIndex == index)
                option.selected = true
            select.appendChild(option)
        })
        select.onchange = () => {
            this.selectedIndex = select.selectedIndex
            this.spinner.innerHTML = this.items[this.selectedIndex]
            if (this.onSelectChangedListener)
                this.onSelectChangedListener()
            dialog.close()
        }
        dialog.getTemplateContainer().appendChild(select)
        select.focus()
    }

    private onGetPrompt(sessionId: number, futureId: number) {
        this.sendAction('onGetPrompt', sessionId, futureId, toAny(this.prompt, StringValue))
    }

    private onSetPrompt(...argv: any[]) {
        this.prompt = fromAny(argv[0], StringValue)
    }

    private onSelect(...argv: any[]) {
        const index = fromAny(argv[0], Int32Value);
        if (this.dialogMode) {
            this.selectedIndex = index
            this.spinner.innerHTML = this.items[index]
            return
        }
        this.spinner.getElementsByTagName('option')[index].selected = true
    }

    private onSetItems(...argv: any[]) {
        if (this.dialogMode) {
            this.items = argv.map(i => fromAny(i, StringValue))
            return
        }
        this.spinner.childNodes.forEach(n=>n.remove())
        for (const item of argv) {
            const option = document.createElement('option');
            option.value = option.text = fromAny(item, StringValue);
            this.spinner.appendChild(option);
        }
    }

    private setOnItemSelectedListener(...argv: any[]) {
        this.onSelectChangedListener = async () => {
            const index = this.dialogMode ? this.selectedIndex : (this.spinner as HTMLSelectElement).selectedIndex
            await this.sendCallback(argv[0], toAny(index, Int32Value))
        }
        this.spinner.onchange = () => this.onSelectChangedListener()
    }
}

export {WidgetSpinnerSession}